package com.tangyuan.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tangyuan.common.payment.AliPayImpl;
import com.tangyuan.common.payment.WxPayImpl;
import com.tangyuan.common.result.Result;
import com.tangyuan.common.result.ResultCodeEnum;
import com.tangyuan.common.util.BeanUtils;
import com.tangyuan.common.util.PhoneNumberUtil;
import com.tangyuan.dto.EnrollRecordDto;
import com.tangyuan.model.Orders;
import com.tangyuan.model.User;
import com.tangyuan.model.UserBalance;
import com.tangyuan.model.activity.*;
import com.tangyuan.result.oConvertUtils;
import com.tangyuan.user.mapper.EnrollRecordMapper;
import com.tangyuan.user.mapper.TicketTypeRecordMapper;
import com.tangyuan.user.service.*;
import com.tangyuan.vo.ActivityEnrollVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @Description: enroll_record
 * @Author: jeecg-boot
 * @Date: 2024-03-20
 * @Version: V1.0
 */
@Service
@Transactional
public class EnrollRecordServiceImpl extends ServiceImpl<EnrollRecordMapper, EnrollRecord> implements IEnrollRecordService {
    @Autowired
    private IUserActivityService userActivityService;
    @Autowired
    private IEnrollService enrollService;
    @Autowired
    private IUserService userService;
    @Autowired
    private ITicketTypeRecordService ticketTypeRecordService;
    @Autowired
    private WxPayImpl wxPayService;
    @Autowired
    private IUserBalanceService userBalanceService;

    @Autowired
    private EnrollRecordMapper enrollRecordMapper;

    @Autowired
    private TicketTypeRecordMapper ticketTypeRecordMapper;

    /**
     * 新增报名
     *
     * @param user
     * @param enroll
     * @return
     */
    @Override
    public Result<Object> saveEnroll(User user, Enroll enroll) {
        UserActivity activity = userActivityService.getById(enroll.getActivityId());
        Result<Object> fail = getJudgement(activity);
        if (!fail.isOk()){
            return fail;
        }
        enroll.setUserId(user.getId());
        enroll.setOrderNo("HD" + oConvertUtils.orderNo());
        enroll.setCreateTime(new Date());
        for (EnrollRecord enrollRecord : enroll.getEnrollRecords()) {
            TicketTypeRecord ticketTypeRecord = ticketTypeRecordService.getById(enroll.getVoteId());
            Result<Object> fail1 = getJudgement(ticketTypeRecord);
            if (!fail1.isOk()){
                return fail1;
            }
            BigDecimal multiply = ticketTypeRecord.getVoteMoney().multiply(new BigDecimal(enroll.getVoteNum()));
            if (multiply.compareTo(enroll.getActivityMoney()) != 0) {
                return Result.build(null,ResultCodeEnum.INCORRECT_PAYMENT_AMOUNT);
            }
            enrollRecord.setActivityId(activity.getId());
            enrollRecord.setUserId(user.getId());
            enrollRecord.setEnrollId(enroll.getId());
            enrollRecord.setVoteId(enroll.getVoteId());
            enrollRecord.setCreateTime(new Date());
            this.save(enrollRecord);
        }
        enrollService.save(enroll);
        Orders orders = new Orders();
        orders.setOrderNo("RM" + oConvertUtils.orderNo());
        orders.setPayType(enroll.getPayType());
        orders.setPayBalance(enroll.getActivityMoney());
        orders.setShopName(activity.getSubject());

        if (enroll.getPayType() == 1) {
            // 调取微信支付
            return wxPayService.wxPay(orders);
        } else if (enroll.getPayType() == 2) {
            // 调取支付宝支付
            return AliPayImpl.pay(orders);
        } else if (enroll.getPayType() == 3) {
            return balancePay(orders, user, enroll);
        } else if (enroll.getPayType() == 4) {

        }
        return Result.ok("报名成功！");
    }

    @Override
    public Result<Object> saveEnrollRecord(User user, EnrollRecordDto enrollRecordDto) {
        boolean number = PhoneNumberUtil.isValidPhoneNumber(enrollRecordDto.getPhone());
        if(!number){
            return Result.build(null,ResultCodeEnum.INCORRECT_PHONE_FORMAT);
        }
        String orderNo = "HD"+oConvertUtils.orderNo();
        UserActivity activity = userActivityService.getById(enrollRecordDto.getActivityId());
        Result<Object> fail = getJudgement(activity);
        if (!fail.isOk()){
            return fail;
        }
        TicketTypeRecord ticketTypeRecord = ticketTypeRecordMapper.selectByAId(enrollRecordDto.getActivityId(), enrollRecordDto.getVoteId());
        Result<Object> fail1 = getJudgement(ticketTypeRecord);
        if (!fail1.isOk()){
            return fail1;
        }
        if (enrollRecordDto.getVoteNum()>ticketTypeRecord.getQuotaNum()){
            return Result.build(null,ResultCodeEnum.QUOTA_CODE_ERROR);
        }
        Boolean isExists = enrollRecordMapper.exists(new LambdaQueryWrapper<EnrollRecord>()
                .eq(EnrollRecord::getUserId, user.getId())
                .eq(EnrollRecord::getActivityId, enrollRecordDto.getActivityId())
                .eq(EnrollRecord::getIsDeleted, 0)
                .eq(EnrollRecord::getIsComplete, 1)
                .eq(EnrollRecord::getIsCancel, 0));
        if(isExists){
            return Result.build(null,ResultCodeEnum.REPEATED_REGISTRATION);
        }
        //保存报名表
        Enroll enroll = new Enroll();
        enroll.setActivityId(enrollRecordDto.getActivityId());
        enroll.setUserId(user.getId());
        enroll.setVoteId(enrollRecordDto.getVoteId());
        enroll.setVoteNum(enrollRecordDto.getVoteNum());
        enroll.setTicketName(ticketTypeRecord.getName());
        enroll.setActivityMoney(enrollRecordDto.getActivityMoney());
        enroll.setOrderNo(orderNo);
        enroll.setCreateTime(new Date());
        enroll.setUpdateTime(new Date());
        enroll.setPayType(enrollRecordDto.getPayType());
        //新建报名表设置为未支付
        enroll.setStatus(0);
        enroll.setIsDeleted(0);
        enrollService.save(enroll);

        //保存活动报名详情表
        EnrollRecord enrollRecord = BeanUtils.copyBean(enroll, EnrollRecord.class);
        enrollRecord.setEnrollId(enroll.getId());
        enrollRecord.setVoteMoney(enrollRecordDto.getActivityMoney());
        enrollRecord.setUserName(enrollRecordDto.getName());
        enrollRecord.setPhone(enrollRecordDto.getPhone());
        enrollRecord.setOrderNo(orderNo);
        this.save(enrollRecord);

        //扣减票种数量
        ticketTypeRecord.setRemainderNum(ticketTypeRecord.getRemainderNum()-enrollRecordDto.getVoteNum());
        ticketTypeRecordService.updateById(ticketTypeRecord);

        Orders orders = new Orders();
        orders.setOrderNo(orderNo);
        orders.setPayType(enroll.getPayType());
        orders.setPayBalance(enroll.getActivityMoney());
        orders.setShopName(activity.getSubject());

        if (enroll.getPayType() == 1) {
            // 调取微信支付
            return wxPayService.wxPay(orders);
        } else if (enroll.getPayType() == 2) {
            // 调取支付宝支付
            return AliPayImpl.pay(orders);
        } else if (enroll.getPayType() == 3) {
            return balancePay(orders, user, enroll);
        } else if (enroll.getPayType() == 4) {

        }else if(enroll.getPayType()==0){
            //支付成功修改报名表状态
            enroll.setStatus(1);
            enroll.setPayTime(new Date());
            enroll.setUpdateTime(new Date());
            enroll.setTransaction("0");
            enrollService.updateById(enroll);

            return Result.ok("报名成功！");
        }

       /* // 活动报名成功,改变用户为已报名
        activity.setIsParticipate(1);
        userActivityService.update();
       */
             return Result.errorPayType("");
    }

    @Override
    public Result<Object> getEnrollListByUserId(Long userId, Long activityId) {
        UserActivity userActivity = userActivityService.getById(activityId);

        List<EnrollRecord> enrollRecordList = enrollRecordMapper.getEnrollListByUserId(userId, activityId);
        ActivityEnrollVo activityEnrollVo = new ActivityEnrollVo();

        activityEnrollVo.setActivityDescribe(userActivity.getActivityDescribe());
        activityEnrollVo.setActivityForm(userActivity.getActivityForm());
        activityEnrollVo.setSubject(userActivity.getSubject());
        activityEnrollVo.setActivityAddress(userActivity.getActivityAddress());
        activityEnrollVo.setStartTime(userActivity.getStartTime());
        activityEnrollVo.setEndTime(userActivity.getEndTime());
        activityEnrollVo.setOrganizerPhone(userActivity.getPhone());

        activityEnrollVo.setPosterUrl(userActivity.getPosterUrl() == null ? "" : userActivity.getPosterUrl());

        BigDecimal voteAllMoney = new BigDecimal(0);
        for (EnrollRecord enrollRecord : enrollRecordList) {
            if (enrollRecord.getIsComplete() == 1 || enrollRecord.getIsCancel() == 0){
                voteAllMoney = voteAllMoney.add(new BigDecimal(String.valueOf(enrollRecord.getVoteMoney())));
            }
        }

        activityEnrollVo.setVoteAllMoney(voteAllMoney);
        activityEnrollVo.setActuallyOrderMoney(voteAllMoney);
        activityEnrollVo.setPosterUrl(userActivity.getPosterUrl()==null?"":userActivity.getPosterUrl());

        activityEnrollVo.setEnrollRecords(enrollRecordList);

        return Result.ok(activityEnrollVo);
    }

    @Override
    public Result<Object> getEnrollTicketTypeName(Long userId, Long activityId) {
      //  List<TicketType> ticketTypeList = enrollRecordMapper.getEnrollTicketTypeName(userId,activityId);
        List<TicketTypeRecord> ticketTypeRecordList =enrollRecordMapper.selectTicketTypeName(activityId);
        return Result.ok(ticketTypeRecordList);
    }

    private static Result<Object> getJudgement(UserActivity activity) {
        if (activity == null) {
            return Result.build(null, ResultCodeEnum.ACTIVE_NOT_EXIST);
        }
        if (activity.getExamine() != 1 && activity.getStatus() != 0) {
            return Result.build(null, ResultCodeEnum.ACTIVITY_HAS_NOT_STARTED);
        }
        //之后
        if (activity.getStartTime().after(new Date())) {
            return Result.build(null, ResultCodeEnum.ACTIVITY_HAS_NOT_STARTED);
        }
        //之前
        if (activity.getEndTime().before(new Date())) {
            return Result.build(null, ResultCodeEnum.ACTIVE_OVER_TIME);
        }
        return Result.ok();
    }

    private static Result<Object> getJudgement(TicketTypeRecord ticketTypeRecord) {
        if (ticketTypeRecord == null) {
            return Result.build(null, ResultCodeEnum.ACTIVE_NOT_EXIST);
        }
        if (ticketTypeRecord.getStartTime().after(new Date())) {
            return Result.build(null, ResultCodeEnum.ACTIVITY_HAS_NOT_STARTED);
        }
        if (ticketTypeRecord.getVoteTime().before(new Date())) {
            return Result.build(null, ResultCodeEnum.ACTIVE_OVER_TIME);
        }
        if (ticketTypeRecord.getRemainderNum()==0){
            return Result.build(null, ResultCodeEnum.ACTIVITY_HAS_NO_TICKETS);
        }
        return Result.ok();
    }

    private Result<Object> balancePay(Orders orders, User user, Enroll enroll) {
        LambdaQueryWrapper<UserBalance> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserBalance::getUserId, user.getId());
        queryWrapper.orderByDesc(UserBalance::getCreateTime);
        queryWrapper.last("limit 1");
        UserBalance balance = userBalanceService.getOne(queryWrapper);
        /*if (user.getPayPwd().isEmpty()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.errorMoney("暂未设置支付密码，请设置支付密码后重试！");
        }
        if (!user.getPayPwd().equals(MD5.encrypt(enroll.getPayPwd()))) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.errorMoney("密码输入错误，请稍后重试！");
        }*/
        if (balance == null || balance.getBalance().compareTo(orders.getPayBalance()) < 0) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.errorMoney("当前余额不足，请使用其他支付方式！");
        }
        UserBalance userBalance = new UserBalance();
        userBalance.setUserId(user.getId());
        userBalance.setType(2);
        userBalance.setTransactionId("BM" + oConvertUtils.orderNo());
        userBalance.setOrderNo(orders.getOrderNo());
        userBalance.setUpBalance(orders.getPayBalance());
        userBalance.setBalance(balance.getBalance().subtract(orders.getPayBalance()));
        userBalance.setCreateTime(new Date());
        userBalanceService.save(userBalance);

        //支付成功修改报名表状态
        enroll.setStatus(1);
        enroll.setPayTime(new Date());
        enroll.setUpdateTime(new Date());
        enroll.setTransaction(userBalance.getTransactionId());
        enrollService.updateById(enroll);

        return Result.ok("报名成功！");
    }

}
